﻿#region using
using System;
using AwesomeTanks.Sources.GameElements.TankElements;
using AwesomeTanks.Sources.PlayerInputs;
using AwesomeTanks.Sources.Screens;
using AwesomeTanks.Sources.Tools;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using AwesomeTanks.Sources.Media;



#endregion

namespace AwesomeTanks.Sources.GameElements
{
    /// <summary>
    /// This class represents a player in AwesomeTank.
    /// </summary>
    public class Player
    {
        #region Fields

        public String PlayerName { get; set; }
        public TeamColor TeamColor { get; set; }

        private int score;

        public int Score
        {
            get { return score; }
            set
            {
                if (value < 0)
                {
                    score = 0;
                }
                else
                {
                    score = value;
                }
            }
        }


        public Tank Tank { get; set; }
        public IControlsState Control { get; set; }
        public Color PlayerColor { get; set; }
        public int Life { get; set; }
        public PlayerIndex PlayerIndex { get; set; }

        #endregion

        #region Constuctors

        /// <summary>
        /// Initializes a new instance of the <see cref="Player"/> class.
        /// </summary>
        /// <param name="name">The name of the player.</param>
        /// <param name="teamcolor">The color corresponding to the team of the player. View <see cref="TeamColor"/>.</param>
        /// <param name="playerColor">The color of the player.</param>
        /// <param name="tank">The tank of the player.</param>
        /// <param name="control">The controls of the player (Gamepad or keyboard for debugging).</param>
        /// <param name="life">The number of life of the player, ie the number of tanks available.</param>
        /// <param name="playerindex">The index of the player.</param>
        public Player(String name, TeamColor teamcolor, Color playerColor, Tank tank, IControlsState control, int life, PlayerIndex playerindex)
        {
            PlayerName = name;
            TeamColor = teamcolor;
            Score = 0;
            Tank = tank;
            Control = control;
            PlayerColor = playerColor;
            Tank.Color = PlayerColor;
            Life = life;
            PlayerIndex = playerindex;
        }

        #endregion

        #region Methods

        public static TeamColor? getTeamByTank(Tank tank)
        {
            foreach (Team team in GameplayScreen.listTeam)
            {

                foreach (Player player in team.ListPlayers)
                {
                    if (player.Tank == tank)
                    {
                        return player.TeamColor;
                    }
                }
            }
            return null;
        }

        #endregion

        #region Update and Draw
        /// <summary>
        /// Updates the player in function of the specified game time.
        /// </summary>
        /// <param name="gameTime">The game time.</param>
        public void Update(GameTime gameTime)
        {
            // GamePad Update for vibration
            if (Control is GamePadControlsState && OptionsMenuScreen.Vibration)
            {
                GamePadControlsState gamepad = (GamePadControlsState)Control;
                gamepad.Update(gameTime);
            }

            if (Tank != null)
            {
                if (Tank.CurrentLife > 0)
                {
                    // Tank speed Update
                    Tank.OldSpeed = Tank.Speed;
                    Tank.Speed = Control.GetTankDirection();

                    // Tank aim update
                    Vector2 aim = Control.GetTankAiming();
                    if (aim != Vector2.Zero)
                    {
                        Tank.Turret.Rotation = new Vector2(aim.Y, aim.X).ToAngle();
                        Tank.Turret.CurrentAiming = new Vector2(aim.X, -aim.Y);
                    }

                    TankAction action = Control.GetTankAction();

                    // Tank special shoot
                    if (action == TankAction.SPECIAL_SHOT)
                    {
                        if (Tank.SecondaryWeapon.CanShoot())
                        {
                            if (!OptionsMenuScreen.MuteEffect)
                            {
                                Sound.RocketShot.Play(Sound.SOUNDEFFECT_VOLUME, 0f, 0f);
                            }
                            Tank.SecondaryWeapon.Fire(Tank.Turret.Position, Tank.Turret.CurrentAiming, this);
                        }
                    }

                    // Tank shoot
                    if (action == TankAction.SHOT)
                    {
                        if (Tank.Weapon.CanShoot())
                        {
                            if (!OptionsMenuScreen.MuteEffect)
                            {
                                Sound.GatlingShot.Play(Sound.SOUNDEFFECT_VOLUME / 6, 0f, 0f);
                            }
                            Tank.Weapon.Fire(Tank.Turret.Position, Tank.Turret.CurrentAiming, this);
                        }
                    }
                }
                else
                {
                    // ReSpawn of the Tank
                    if (Life > 0)
                    {
                        Life--;
                        Tank.CurrentLife = Tank.MaxLife;
                        Tank.Rotation = 0;
                        //CHECKER COLLISION TANK - SPAWN

                        PlayerIndex spawnPlayerIndex = PlayerIndex;
                        //Update the position of the tank's hitboxes
                        this.Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                        this.Tank.UpdateHitboxes();
                        bool SpawnFound = false;
                        bool collisionFound = false;

                        while (!SpawnFound)
                        {
                            foreach (Tank tank in GameplayScreen.listTank)
                            {
                                if (this.Tank != tank)
                                {
                                    if (Collision.TankCollisions.TankCollision(this.Tank, tank))
                                    {
                                        collisionFound = true;
                                        break;
                                    }
                                }
                            }
                            if (collisionFound)
                            {
                                switch (spawnPlayerIndex)
                                {
                                    case PlayerIndex.One:
                                        spawnPlayerIndex = PlayerIndex.Two;
                                        Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                        break;
                                    case PlayerIndex.Two:
                                        spawnPlayerIndex = PlayerIndex.Three;
                                        Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                        break;
                                    case PlayerIndex.Three:
                                        spawnPlayerIndex = PlayerIndex.Four;
                                        Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                        break;
                                    case PlayerIndex.Four:
                                        spawnPlayerIndex = PlayerIndex.One;
                                        Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                        break;
                                }
                                this.Tank.UpdateHitboxes();
                                collisionFound = false;
                            }
                            else
                            {

                                SpawnFound = true;
                            }
                        }




                        /*while (!SpawnFound)
                        {
                            foreach (Tank tank in GameplayScreen.listTank)
                            {
                                if (tank != this.Tank)
                                {
                                    this.Tank.UpdateHitboxes();

                                    if (Collision.TankCollisions.TankCollision(this.Tank, tank))
                                    {
                                        switch (spawnPlayerIndex)
                                        {
                                            case PlayerIndex.One:
                                                spawnPlayerIndex = PlayerIndex.Two;
                                                Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                                break;
                                            case PlayerIndex.Two:
                                                spawnPlayerIndex = PlayerIndex.Three;
                                                Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                                break;
                                            case PlayerIndex.Three:
                                                spawnPlayerIndex = PlayerIndex.Four;
                                                Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                                break;
                                            case PlayerIndex.Four:
                                                spawnPlayerIndex = PlayerIndex.One;
                                                Tank.Position = GameplayScreen.map.getSpawn(spawnPlayerIndex);
                                                break;
                                        }
                                    }
                                    else { 
                                        
                                        SpawnFound = true; }
                                }
                            }
                        }*/




                        //Vibration
                        if (Control is GamePadControlsState && OptionsMenuScreen.Vibration)
                        {
                            GamePadControlsState gamepad = (GamePadControlsState)Control;
                            gamepad.StartVibration(GamePadControlsState.TANK_DESTRUCTION_VIBRATION_DURATION_MS, GamePadControlsState.TANK_DESTRUCTION_VIBRATION_INTENSITY);
                        }
                    }
                    else
                    {
                        GameplayScreen.listTank.Remove(Tank);
                        Tank = null;
                        if (Control is GamePadControlsState && OptionsMenuScreen.Vibration)
                        {
                            GamePadControlsState gamepad = (GamePadControlsState)Control;
                            gamepad.StartVibration(GamePadControlsState.PLAYER_DEATH_VIBRATION_DURATION_MS, GamePadControlsState.PLAYER_DEATH_VIBRATION_INTENSITY);
                        }
                        return;
                    }
                }

                Tank.Update(gameTime);
                Tank.Weapon.Update(gameTime);
                Tank.SecondaryWeapon.Update(gameTime);
            }
        }

        /// <summary>
        /// Draws the player in the specified spritebatch.
        /// </summary>
        /// <param name="spritebatch">The spritebatch.</param>
        public void Draw(SpriteBatch spritebatch)
        {
            this.Tank.Draw(spritebatch);
        }
        #endregion
    }
}
